<?php

namespace App\Extend\Admin\Common\Html;

use App\Extend\Admin\Common\Html\Input;

/**
 * @example echo $form->setExt(['id'=>'id'])->hidden('id');
 */
class EasyForm
{
    /**
     * @var \app\admin\extend\common\html2\Input
     */
    public $input;

    /**
     * @var LayuiForm
     */
    public $layuiForm;

    /**
     * @var string|array
     */
    public $keyList;

    public $ext = [];       // 表单扩展字段
    public $label = '';     // 表单前面的标题
    public $clues = '';     // 表单后面的提示语
    public $name = '';      // 表单的name字段
    public $verify = [];    // 验证规则
    public $placeholder = '';   // 表单内的提示语
    public $isRequire = false;  // 必填
    public $inputInlineArr = [];    // 行内表单数组
    public $isInline = false;       // 是否是行内表单
    public $isLong = false;         // 是否是长表单


    public function __construct($data = [], $keyList='') {
        $this->input = new Input($data);
        $this->layuiForm = new LayuiForm();

        $this->keyList = $keyList;
    }

    /**
     * hidden
     * @example echo $form->setExt(['id'=>'id'])->hidden('id')
     * @param $name
     * @param $value
     * @return String
     */
    public function hidden($name, $value = false) {
        $this->inputStart($name);
        $ext = $this->flashExt();

        $this->inputEnd();
        return $this->input->field($name, $value)->hidden($ext);
    }

    /**
     * password
     * @example echo $form->setExt(['id'=>'id'])->setLabel('密码', true)->setClues('请输入密码')->password('password', '');
     * @param $name
     * @param $value
     * @return string
     */
    public function password($name, $value = false) {
        $this->inputStart($name);

        $ext = $this->flashExt();
        $input = $this->input->field($name, $value)->password($ext);
        $label = $this->flashLabel();
        $clues = $this->flashClues();

        $isLong = $this->flashIsLong();
        $this->layuiForm->setIsLong($isLong);

        $this->inputEnd();
        return $this->layuiForm->itemOne($label, $input, $clues);
    }

    /**
     * text
     * @example echo $form->setIsLong(true)->setExt(['class'=>'aa'])->setLabel('昵称', true)->setClues('请输入昵称')->text('nickname');
     * @param $name
     * @param $value
     * @return EasyForm|string
     */
    public function text($name, $value = false) {
        $this->inputStart($name);

        $ext = $this->flashExt();
        $input = $this->input->field($name, $value)->text($ext);
        $label = $this->flashLabel();
        $clues = $this->flashClues();

        if($this->getIsInline()) {
            $inputInline = $this->layuiForm->inlineOne($label, $input);
            $this->addInlineArr($inputInline);
            $this->inputEnd();
            return $this;
        }

        $isLong = $this->flashIsLong();
        $this->layuiForm->setIsLong($isLong);

        $this->inputEnd();
        return $this->layuiForm->itemOne($label, $input, $clues);
    }

    /**
     * textarea
     * @example echo $form->setExt(['id'=>'a'])->setLabel('简介')->setClues('请输入简介')->textarea('desc');
     * @param $name
     * @param $value
     * @return EasyForm|string
     */
    public function textarea($name, $value = false) {
        $this->inputStart($name);

        $ext = $this->flashExt();
        $ext['class'] = 'layui-textarea';
        $input = $this->input->field($name, $value)->textarea($ext);
        $label = $this->flashLabel();
        $clues = $this->flashClues();

        if($this->getIsInline()) {
            $inputInline = $this->layuiForm->inlineOne($label, $input);
            $this->addInlineArr($inputInline);
            $this->inputEnd();
            return $this;
        }

        $this->inputEnd();
        return $this->layuiForm->textarea($label, $input, $clues);
    }

    /**
     * checkbox
     * @example echo $form->setLabel('爱好')->checkbox('hobby', ['1'=>'读书', '2'=>'写字']);
     * @param $name
     * @param $data
     * @param $value
     * @return EasyForm|string
     */
    public function checkbox($name, $data, $value = false) {
        $this->inputStart($name);

        $ext = $this->flashExt();
        $input = $this->input->field($name, $value)->checkboxList($data, $ext);
        $label = $this->flashLabel();
        $clues = $this->flashClues();

        if($this->getIsInline()) {
            $inputInline = $this->layuiForm->inlineOne($label, $input);
            $this->addInlineArr($inputInline);
            $this->inputEnd();
            return $this;
        }

        $this->inputEnd();
        return $this->layuiForm->itemOne($label, $input, $clues);
    }

    /**
     * select
     * @example echo $form->setExt('id'=>'a')->setLabel('年龄段', true)->setClues('请选择年龄段')->select('age', ['1'=>'少年', '2'=>'青年', '3'=>'老年']);
     * @param $name
     * @param $data
     * @param $value
     * @return EasyForm|string
     */
    public function select($name, $data, $value = false) {
        $this->inputStart($name);

        $ext = $this->flashExt();
        $input = $this->input->field($name, $value)->select($data, $ext);
        $label = $this->flashLabel();
        $clues = $this->flashClues();

        if($this->getIsInline()) {
            $inputInline = $this->layuiForm->inlineOne($label, $input);
            $this->addInlineArr($inputInline);
            $this->inputEnd();
            return $this;
        }

        $isLong = $this->flashIsLong();
        $this->layuiForm->setIsLong($isLong);

        $this->inputEnd();
        return $this->layuiForm->itemOne($label, $input, $clues);
    }

    /**
     * radio
     * @example echo $form->setExt(['class'=>'a'])->setLabel('性别')->setClues('请选择性别')->radio('sex', ['1'=>'男', '2'=>'女']);
     * @param $name
     * @param $data
     * @param $value
     * @return EasyForm|string
     */
    public function radio($name, $data, $value = false) {
        $this->inputStart($name);

        $ext = $this->flashExt();
        $input = $this->input->field($name, $value)->radio($data, $ext);
        $label = $this->flashLabel();
        $clues = $this->flashClues();

        if($this->getIsInline()) {
            $inputInline = $this->layuiForm->inlineOne($label, $input);
            $this->addInlineArr($inputInline);
            $this->inputEnd();
            return $this;
        }

        $this->inputEnd();
        return $this->layuiForm->itemOne($label, $input, $clues);
    }

    /**
     * 一组行内 input
     *
     * @example $form->setLabel('地区')->setClues('请选择地区')->setIsInline(true)
     * ->setExt(['id'=>'t1'])->text('t1')
     * ->setExt(['id'=>'t2'])->text('t2')
     * ->inputSome();
     *
     * @param $inputInlineList
     * @return string
     */
    public function inputSome($inputInlineList = []) {
        $label = $this->flashLabel();
        $clues = $this->flashClues();
        if(!$inputInlineList) {
            $inputInlineList = $this->flashInlineArr();
        }

        $this->flashIsInline();
        return $this->layuiForm->itemList($label, $inputInlineList, $clues);
    }

    public function setKeyList($keyList) {
        $this->keyList = $keyList;
        return $this;
    }

    public function getKey($key='') {
        // 获取全部
        if(!$key) {
            return $this->keyList;
        }

        // 数组
        if(is_array($this->keyList)) {
            return $this->keyList[$key] ?? '';
        }

        // 对象
        if(is_object($this->keyList)) {
            return $this->keyList->$key;
        }

        // 字符串(类名)
        if(is_string($this->keyList) and $this->keyList) {
            $this->keyList = new \ReflectionClass($this->keyList);
            $this->keyList = $this->keyList->getConstants();
            return $this->keyList[$key];
        }
        return '';
    }

    // 表单开始
    public function inputStart($name) {
        // 加前缀是为了区分内置的验证规则
        $verify = '_' . $name;
        $this->addVerify($verify);

        $this->setName($name);
        if(!$this->getLabel()) {
            $label = $this->getKey($name);
            $this->setLabel($label);
        }

        if(!$this->getPlaceholder()) {
            $this->setPlaceholder('请输入' . $this->label);
        }
    }

    // 表单结束
    public function inputEnd() {
        $this->flashPlaceholder();
        $this->flashVerify();
        $this->flashName();
        $this->flashRequire();
        $this->flashLabel();
    }

    // 设置短连线
    public function getShortLine() {
        $inline = $this->layuiForm->getShortLine();
        $this->addInlineArr($inline);
    }

    // 必填
    public function setRequire($isRequire = true) {
        $this->isRequire = $isRequire;
        if($isRequire) {
            $this->addVerify('required');
        }
        return $this;
    }

    public function getRequire() {
        return $this->isRequire;
    }

    public function flashRequire() {
        $isRequire = $this->getRequire();
        $this->setRequire(false);
        return $isRequire;
    }

    // 表单验证规则
    public function setVerify($verifyList) {
        if(!is_array($verifyList)) {
            $verifyList = [$verifyList];
        }
        $this->verify = $verifyList;
        return $this;
    }

    public function addVerify($verify) {
        if(is_array($verify)) {
            $this->verify = array_merge($this->verify, $verify);
        } else {
            $this->verify[] = $verify;
        }
        return $this;
    }

    public function getVerify() {
        return $this->verify;
    }

    public function flashVerify() {
        $verify = $this->getVerify();
        $this->setVerify([]);
        return $verify;
    }

    // 表单内提示语
    public function setPlaceholder($placeholder) {
        $this->placeholder = $placeholder;
        return $this;
    }

    public function getPlaceholder() {
        return $this->placeholder;
    }

    public function flashPlaceholder() {
        $placeholder = $this->getPlaceholder();
        $this->setPlaceholder('');
        return $placeholder;
    }

    // 表单 name
    public function setName($name) {
        $this->name = $name;
        return $this;
    }

    public function getName() {
        return $this->name;
    }

    public function flashName() {
        $name = $this->getName();
        $this->setName('');
        return $name;
    }

    // 是否是长表单
    public function setIsLong($isLong) {
        $this->isLong = $isLong;
        return $this;
    }

    public function getIsLong() {
        return $this->isLong;
    }

    public function flashIsLong() {
        $isLong = $this->getIsLong();
        $this->setIsLong(false);
        return $isLong;
    }

    // 是否是行内表单
    public function setIsInline($isInline) {
        $this->isInline = $isInline;
        return $this;
    }

    public function getIsInline() {
        return $this->isInline;
    }

    public function flashIsInline() {
        $isInline = $this->getIsInline();
        $this->setIsInline(false);
        return $isInline;
    }

    // 行内表单数组
    public function addInlineArr($inputInline) {
        $this->inputInlineArr[] = $inputInline;
        return $this;
    }

    public function clearInlineArr() {
        $this->inputInlineArr = [];
        return $this;
    }

    public function getInlineArr() {
        return $this->inputInlineArr;
    }

    public function flashInlineArr() {
        $arr = $this->getInlineArr();
        $this->clearInlineArr();
        return $arr;
    }

    // 处理 clues
    public function getClues() {
        return $this->clues;
    }

    public function setClues($clues) {
        $this->clues = $clues;
        return $this;
    }

    public function flashClues() {
        $clues = $this->getClues();
        $this->setClues('');
        return $clues;
    }

    // 获取 label, 可能带星号
    public function getLabel() {
        if(!$this->label) {
            return $this->label;
        }
        $star = '';
        if($this->getRequire()) {
            $star = '<span style="color:red">*</span>';
        }
        return $star . $this->label;
    }

    public function setLabel($label, $isRequire=false) {
        if($isRequire) {
            $this->setRequire($isRequire);
            $this->addVerify('required');
        }
        $this->label = $label;
        return $this;
    }

    public function flashLabel() {
        $label = $this->getLabel();
        $this->setLabel('');
        return $label;
    }

    // 处理ext
    public function setExt($ext) {
        $this->ext = $ext;
        return $this;
    }

    public function flashExt() {
        $ext = $this->getExt();
        $this->setExt([]);

        $ext['lay-verify'] = implode('|', $this->getVerify());
        $ext['placeholder'] = $this->getPlaceholder();

        $title = $this->label;
        $ext = array_merge($this->layuiForm->getConvExt($this->getName(), $title), $ext);
        return $ext;
    }

    public function getExt() {
        return $this->ext;
    }
}